07. Functional Counting

Step 5. Fun with Functional Word Counting

In order to really impress your manager, you've will need to implement the final word count sorting using only functional programming techniques.

You open the utility class src/main/java/com/udacity/webcrawler/WordCounts.java and you notice it was written when Java 7 was the hot new thing. Did I mention it's legacy code? Let's update it to take advantage of the newer functional programming features of Java!

You will see just one non-private method:

static Map<String, Integer> sort(Map<String, Integer> wordCounts, int popularWordCount)

The input to this method is a Map of all the words and counts your crawler encountered, and a number popularWordCount which is a copy of the value of the popularWordCount option from the JSON crawl configuration.

Your new sort method must return a new Map that contains up to popularWordCount entries from the original map, but sorted according to the following specification (which should look familiar):

  • The keys and values should be sorted so that the more frequent words come first. If multiple words have the same frequency, prefer longer words rank higher. If multiple words have the same frequency and length, use alphabetical order to break ties (the word that comes first in the alphabet ranks higher).

But wait, what exactly does it mean to use only functional programming techniques? Simple: Don't use any for loops. That's right, no for loops at all. Instead, you will have to process the wordCounts map using only the Java Stream API, lambdas, and method references. The new method should be a single return statement with a "chain" of Stream operations. You are allowed to reuse the WordCountComparator class.

Hint: To get started, turn wordCounts into a Stream. Your method should start like this: return wordCounts.entrySet().stream()….

Recall that the order of the returned map is important, so you should take that into account when choosing a Collector to terminate the Stream.

When you are done, check your code against the unit tests:

mvn test -Dtest=WordCountsTest